package com.hyk.commonLib.common.utils;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;

import com.hyk.commonLib.R;

import java.util.ArrayList;
import java.util.Stack;

/**
 * Created by 贺玉琨 on 2019/3/13.
 */
public class ActivityManageUtils {
    private static final Stack<Activity> ACTIVITY_STACK = new Stack<>();
    private static int mActivityCount = 0;

    public static void init() {
        ((Application) AppUtils.getAppContext()).registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                ActivityManageUtils.activityCreated(activity);
            }

            @Override
            public void onActivityStarted(Activity activity) {
                mActivityCount++;
            }

            @Override
            public void onActivityResumed(Activity activity) {

            }

            @Override
            public void onActivityPaused(Activity activity) {

            }

            @Override
            public void onActivityStopped(Activity activity) {
                mActivityCount--;
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {
                ActivityManageUtils.activityDestroyed(activity);
            }
        });
    }

    public static void activityCreated(Activity activity) {
        synchronized (ACTIVITY_STACK) {
            ACTIVITY_STACK.add(activity);
        }
    }

    public static void activityDestroyed(Activity activity) {
        synchronized (ACTIVITY_STACK) {
            ACTIVITY_STACK.remove(activity);
        }
    }

    public static <T extends Activity> T getFirst() {
        return (T) getFirst(Activity.class);
    }

    public static <T extends Activity> T getFirst(Class<? extends T> clazz) {
        return getFirst(clazz, true);
    }

    public static <T extends Activity> T getFirst(Class<? extends T> clazz, boolean includeSubClass) {
        for (Activity activity : ACTIVITY_STACK) {
            if (includeSubClass ? clazz.isAssignableFrom(activity.getClass()) : clazz == activity.getClass()) {
                return (T) activity;
            }
        }
        return null;
    }

    public static <T extends Activity> T getLast() {
        return (T) getLast(Activity.class);
    }

    public static <T extends Activity> T getLast(Class<? extends T> clazz) {
        return getLast(clazz, true);
    }

    public static <T extends Activity> T getLast(Class<? extends T> clazz, boolean includeSubClass) {
        for (int i = ACTIVITY_STACK.size() - 1; i >= 0; i--) {
            Activity activity = ACTIVITY_STACK.get(i);
            if (includeSubClass ? clazz.isAssignableFrom(activity.getClass()) : clazz == activity.getClass()) {
                return (T) activity;
            }
        }
        return null;
    }

    public static <T extends Activity> T getPrev(Activity activity) {
        for (int i = ACTIVITY_STACK.size() - 1; i >= 0; i--) {
            Activity tmp = ACTIVITY_STACK.get(i);
            if (tmp == activity && i != 0) {
                return (T) ACTIVITY_STACK.get(i - 1);
            }
        }
        return null;
    }

    public static <T extends Activity> boolean has(Class<? extends T> clazz) {
        return has(clazz, true);
    }

    public static <T extends Activity> boolean has(Class<? extends T> clazz, boolean includeSubClass) {
        return getFirst(clazz, includeSubClass) != null;
    }

    public static Activity getCurrentActivity() {
        if (ACTIVITY_STACK.isEmpty()) return null;
        return ACTIVITY_STACK.lastElement();
    }

    public static void finishCurrentActivity() {
        Activity activity = ACTIVITY_STACK.firstElement();
        if (activity != null) activity.finish();
    }

    public static void finishFirst() {
        finishFirst(Activity.class);
    }

    public static void finishLast() {
        finishLast(Activity.class);
    }

    public static void finishFirst(Class<? extends Activity> clazz) {
        finishFirst(clazz, true);
    }

    public static void finishLast(Class<? extends Activity> clazz) {
        finishLast(clazz, true);
    }

    public static void finishFirst(Class<? extends Activity> clazz, boolean includeSubClass) {
        Activity activity = getFirst(clazz, includeSubClass);
        if (activity != null) activity.finish();
    }

    public static void finishLast(Class<? extends Activity> clazz, boolean includeSubClass) {
        Activity activity = getLast(clazz, includeSubClass);
        if (activity != null) activity.finish();
    }

    public static void finishAll(Class<? extends Activity> clazz) {
        finishAll(clazz, true, -1);
    }

    public static void finishAll(Class<? extends Activity> clazz, boolean includeSubClass) {
        finishAll(clazz, includeSubClass, -1);

    }

    public static void finishAll(Class<? extends Activity> clazz, int limit) {
        finishAll(clazz, true, limit);
    }

    public static void finishAll(Class<? extends Activity> clazz, boolean includeSubClass, int limit) {
        for (Activity activity : ACTIVITY_STACK) {
            if (includeSubClass ? clazz.isAssignableFrom(activity.getClass()) : clazz == activity.getClass()) {
                activity.finish();
                if (limit != -1 && (--limit) == 0) {
                    return;
                }
            }
        }
    }

    public static void finishUntil(Class<? extends Activity> clazz) {
        finishUntil(clazz, true);
    }

    public static void finishUntil(Class<? extends Activity> clazz, boolean includeSubClass) {
        for (int i = ACTIVITY_STACK.size() - 1; i >= 0; i--) {
            Activity activity = ACTIVITY_STACK.get(i);
            if (includeSubClass ? clazz.isAssignableFrom(activity.getClass()) : clazz == activity.getClass()) {
                return;
            }
            activity.finish();
        }
    }

    public static void finishAllExcept(Class<? extends Activity> clazz) {
        finishAllExcept(clazz, false);
    }

    public static void finishAllExcept(Class<? extends Activity> clazz, boolean cancelAnim) {
        for (Activity activity : ACTIVITY_STACK) {
            if (clazz != activity.getClass()) {
                if (cancelAnim) activity.overridePendingTransition(0, R.anim.no_effect);
                activity.finish();
            }
        }
    }

    public static boolean isForeground() {
        return mActivityCount > 0;
    }

    public static void startActivities(Context context, Intent... intents) {
        ArrayList<Intent> intentList = new ArrayList<>();
        for (Intent intent : intents) {
            if (intent != null) intentList.add(intent);
        }
        if (intentList.isEmpty()) return;
        context.startActivities(intentList.toArray(new Intent[0]));
    }

    public static void startActivity(Context context, Intent intent) {
        if (!(context instanceof Activity)) {
            context = AppUtils.getAppContext();
        }
        if (context instanceof Application) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        context.startActivity(intent);
    }

    public static void exit() {
        try {
            synchronized (ACTIVITY_STACK) {
                for (Activity activity : ACTIVITY_STACK) {
                    if (null != activity) {
                        activity.finish();
                    }
                }
                ACTIVITY_STACK.clear();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
